﻿using System;
using System.Reflection;

namespace 反射
{
    class Charactor
    {
        public string _name { get; set; }
        public float _heigth;

        public Charactor(){}
        public Charactor(string  name,float  heigth)
        {
            _name = name;
            _heigth = heigth;
        }

        public void Show()
        {
            Console.WriteLine("name:" + _name+"heigth:"+_heigth);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //1.
            //--------------获得类型的方法 
            Type charactorType = typeof(Charactor);
            Type t1 = new Charactor().GetType();
            Type t2 = Type.GetType("反射.Charactor"); 
            //Assembly assembly = Assembly.LoadFrom("程序集文件路径");//通过程序集查找也是可行的(细品为啥子注释)
            //Type t3 = assembly.GetType("className");
            //--------------获取程序集的方法
            Assembly assem = charactorType.Assembly;//通过一个程序集下的任意一个对象获取当前程序集 
            Assembly assem1 = Assembly.GetExecutingAssembly();//同上，这样更专业

            //2.
            //Type中重要的几个类,以下获取所有公开成员除非再方法中添加BindingFlags
            FieldInfo[] fis = charactorType.GetFields(BindingFlags.Default);
            PropertyInfo[] prs = charactorType.GetProperties();
            //获取所有构造函数,如果返回值不是数组的重载那么默认获取无参函数
            ConstructorInfo[] ctors = charactorType.GetConstructors();
            //获取某个方法的参数
            ParameterInfo[] pars = ctors[1].GetParameters();
            //获取类中所有方法,包括属性中 的get;set;(默认仅限公开)
            MethodInfo[] methods = charactorType.GetMethods();

            //3.
            //3.1--------通过Activator创建实列对象(默认调用无参构造函数,所以在默认情况下用此方法对象必须要有默认构造函数)
            object charactor1 = Activator.CreateInstance(charactorType);//创建实列对象          
            object charactor2 = Activator.CreateInstance(charactorType,"Josiah",1.8f);//包含参数构造函数
            //低端操作
            FieldInfo heigth = charactorType.GetField("_heigth");
            //给字段赋值
            heigth.SetValue(charactor1, 20);//第一个参数是对象,就是说要给那个已经实列的对象赋值
            heigth.SetValue(charactor1, 20 );//第一个参数是对象,就是说要给那个已经实列的对象赋值
            //方法操作
            MethodInfo showMethod = charactorType.GetMethod("Show");
            showMethod.Invoke(charactor1, null);//无参数直接传递null      
            //3.2--------通过类的ConstructorInfo创建对象(可以调用含参构造函数)
            Type[] ctorParamTypes = new Type[2]
            {
                typeof(string),
                typeof(float)
            };//如果长度为0表示无元素,言外之意得到无参构造函数            
            ConstructorInfo ctor = charactorType.GetConstructor(ctorParamTypes);
            Object[] paramObjs = new Object[2]
            {
                "Celia",
                1.73f
            };
            Object concreate = ctor.Invoke(paramObjs); //Inovke中填入的是方法参数的数组若无params传递null即可
            Charactor celia = concreate as Charactor;     
            celia.Show();
            //3.3-----------通过程序集Assembly创建对象
            Assembly assembly = Assembly.GetExecutingAssembly();
            assembly.CreateInstance(charactorType.Name);



            Console.ReadKey();
        }
    } 
}